<?php
/**
 * winbinder 패키지 
 * 
 * 
 * @package php.ui.winbinder
 */

/**
 * WBComponent
 *
 * @package php.ui.winbinder
 */
class WBComponent extends WBObject { 

	private $_defaultEvent = array();
	private $_userEvent = array();
	protected $_isCreated = false;
	private $_instance = null;
	private $_hwnd = null;
	
	private $_maximumWidth = 0;
	private $_maximumHeight = 0;
	private $_minimumWidth = 0;
	private $_minimumHeight = 0;	

	/**
	 * WBComponent 생성자 
	 *
	 * 내부적으로 id 속성이 지정되어 있지 않으면 id를 자동으로 생성해서 등록한다. 
	 *
	 * @param array $options WBComponent에 설정될 옵션 리스트 
	 */
	public function __construct($options = array()) { 

		parent::__construct($options);

		// 객체가 생성되기 전에 실행되는 함수 
		$this->initCreate();

		// 객체 생성 
		$this->create();

		// 객체  생성된 후 설정되는 함수 
		$this->initComponent();
	}

	public function __destruct() { 
		parent::__destruct();
		
		unset($this->_defaultEvent);
		unset($this->_userEvent);
		unset($this->_isCreated);
		unset($this->_instance);
		unset($this->_hwnd);
		unset($this->_maximumWidth);
		unset($this->_maximumHeight);
		unset($this->_minimumWidth);
		unset($this->_minimumHeight);
	}	
	
	/**
	 * 객체가 생성되기 이전의 환경 설정 
	 *
	 *
	 */
	protected function initCreate() { 

	}

	/**
	 * 기본 이벤트 설정 
	 */
	protected function initEvent() { 

		parent::initEvent();

		$this->setEvent('create', 'onCreate');
		$this->setEvent('resize', 'onResize');
		$this->setEvent('redraw', 'onRedraw');	

	}

	/**
	 * WBComponent 기본 설정 
	 *
	 */
	protected function initComponent() { 


	} 

	/** 
	 * instance 얻어오기 
	 *
	 * @return int WBComponent instance 
	 */
	public function getInstance() { 
		return $this->_instance;
	}

	/** 
	 * instance 설정하기 
	 *
	 * @param int $instance 
	 */
	public function setInstance($instance) { 
		$this->_instance = $instance;
	}


	/**
	 * 객체 생성 
	 *
	 * create 이벤트 실행 
	 */
	public function create() { 

		// 객체 생성 
		if($this->_instance) { 
			$this->setInstance($this->getInstance());
		} else { 
			if (!$this->_isCreated) { 
				// 객체 생성 이전에 실행되는 이벤트 
				//$this->fireEvent('create');

				$this->setInstance($this->createComponent());

				$this->_isCreated = true;
			}
		}
	}

	/**
	 * 객체 생성 실제 정의 , instance 생성 
	 *
	 * @return int WBComponent의 instance 
	 */
	protected function createComponent() { 
		return null;	
	}

	/**
	 * 최소사이즈 설정 
	 *
	 */
	public function setMinimumSize($width = 0, $height = 0){
		$this->_minimumWidth = $width;
		$this->_minimumHeight = $height;
	}

	/** 
	 * 최소 사이즈 얻어오기 
	 *
	 */
	public function getMinimumSize() { 
		return array(
			'width'		=> ($this->_minimumWidth)	? $this->_minimumWidth	: 0, 
			'height'	=> ($this->_minimumHeight)	? $this->_minimumHeight	: 0,
		);
	}

	/**
	 * 최대 사이즈 설정 
	 *
	 */
	public function setMaximumSize($width = 0, $height = 0) {
		$this->_maximumWidth = $width;
		$this->_maximumHeight = $height;
	}

	/**
	 * 최대 사이즈 얻어오기 
	 *
	 */
	public function getMaximumSize() { 
		return array(
			'width'		=> ($this->_maximumWidth)	? $this->_maximumWidth	: 0, 
			'height'	=> ($this->_maximumHeight)	? $this->_maximumHeight	: 0,
		);
	}

	/**
	 * 레이아웃 실행 
	 *
	 */
	public function doLayout() { 

	}

	/**
	 * 다시 그리기 실행 
	 *
	 */ 
	public function repaint($graphics) { 
		
	}

	/**
	 * 지정한 영역을 다시 그림 
	 *
	 * @param bool $now  true : 지금 즉시, false : 나중에(?)
	 */
	public function refresh($now = false) { 
		$arg = func_get_args();

		if (sizeof($arg) == 1) { 
			return wb_refresh($this->getInstance(), $now);
		} else { 
			return wb_refresh($this->getInstance(), $arg[1], $arg[2], $arg[3], $arg[4], $now);
		}
	}

	/**
	 * 클래스 상수 얻어옴 
	 *
	 * @return int 클래스 상수 
	 */
	public function getClass() { 
		return wb_get_class($this->getInstance());
	}

	/**
	 * focus 얻기 
	 * 
	 * @return int focus 를 가지고 있는 instance 
	 */ 
	public function getFocus() { 
		return wb_get_focus();
	}

	
	/**
	 * 현재 WBComponent에 focus 설정 
	 *
	 * @return bool 
	 */
	public function setFocus() { 
		return wb_set_focus($this->getInstance());
	}

	/**
	 * 현재 WBComponent id 가지고 오기 
	 *
	 * @param int 
	 */
	public function getId() { 
		return wb_get_id($this->getInstance());
	}

	/**
	 * 상위 WBComponent instance 가져오기 
	 *
	 * @param int $item TreeView의 item 
	 * @return int instance 
     *
	 */ 
	public function getParent($item = null) { 
		return wb_get_parent($this->getInstance(), $item);
	}

	/**
	 * 현재 WBComponent의 Child Component 개수 얻어오기 
	 *
	 * @return int 
	 */
	public function getItemCount() { 
		return wb_get_item_count($this->getInstance());
	}

	/**
	 * 현재 WBComponent의 Child Component 의 instance 리스트 
	 *
	 * @return array 
	 */
	public function getItemList() { 
		return wb_get_item_list($this->getInstance());
	}

	/**
	 * 현재 위치 가지고 오기 
	 *
	 * @param bool $clientarea true이면 실제 영역, false 이면 전체 영역 
	 * @return array 시작 위치 
	 */
	public function getPosition($clientarea = false) { 
		$arr = wb_get_position($this->getInstance(), $clientarea);

		return array('x' => $arr[0], 'y' => $arr[1]);
	}

	/**
	 * 현재 위치 설정 
	 *
	 * @param int $x x좌표 
	 * @param int $y y좌표 
	 * @return bool 
	 */
	public function setPosition($x = WBC_CENTER, $y = WBC_CENTER) { 
		return wb_set_position($this->getInstance(), $x, $y);
	}

	/**
	 * 윈도우 또는 컨트롤 크기 가져오기 
	 *
	 * @param bool $lparam true 이면 실제 표시영역
	 * @return array 
	 */
	public function getSize($lparam = false) { 
		$arr = wb_get_size($this->getInstance(), $lparam);
		
		if (is_array($arr)) { 
			return array('width' => $arr[0], 'height' => $arr[1]);
		} else { 
			return $arr;
		}
	}

	/**
	 * 기본크기 얻어오기 
	 *
	 * @return array 
	 */
	public function getPreferedSize() { 
		return $this->getSize();
	}

	/**
	 * 윈도우 또는 컨트롤 크기 조정하기 
	 *
	 * @param int $width 
	 * @param int $height 
	 */
	public function setSize($width, $height = null) { 
		$bool = false;

		if (is_null($height)) { 
			$bool = wb_set_size($this->getInstance(), $width);			
		} else { 
			$bool = wb_set_size($this->getInstance(), $width, $height);
		}

		$this->fireEvent('resize');

		return $bool;
	}

	/**
	 * text, caption 설정 
	 *
	 * @param int $item 
	 * @param int $subitem
	 * @return string 
	 */
	public function getText($item = null, $subitem = null) { 
		return wb_get_text($this->getInstance(), $item, $subitem);
	}

	/**
	 * text,caption 설정하기 
	 *
	 * @param string $text 설정할 텍스트 
	 * @param int $item 
	 * @param int $subitem 
	 *
	 */
	public function setText($text, $item = null, $subitem = null) { 
		return wb_set_text($this->getInstance(), $text, $item, $subitem);
	}

	/**
	 * 보이기 여부 
	 *
	 * @return bool 
	 */
	public function isVisible() { 
		return wb_get_visible($this->getInstance());
	}

	/**
	 * 보이기 여부 설정 
	 *
	 * @param bool $isVisible 
	 */
	public function setVisible($isVisible = true) { 
		wb_set_visible($this->getInstance(), $isVisible);
	}

	/**
	 * 이미지 설정하기 
	 *
	 * @param int $source 
	 * @param int $transparentcolor
	 * @param int $index 
	 * @param int $param 
	 */
	public function setImage($source, $transparentcolor = NOCOLOR, $index = 1, $param = 0) { 

		if (is_string($source)) { 
			$source = WBImage::loadFile($source);
		} 

		return wb_set_image($this->getInstance(), WBApplication::getInstance($source), $transparentcolor, $index, $param);
	}

	/**
	 * 활성 영역 설정하기 
	 *
	 */
	public function setArea($type, $x = 0, $y = 0, $width = 0, $height = 0){
		return wb_set_area($this->getInstance(), wbconstant($type), $x, $y, $width, $height);
	}

	/**
	 * style 설정하기 
	 *
	 * @param int $style 설정될 style 
	 * @param bool $set 
	 */
	public function setStyle($style, $set = true ) { 
		return wb_set_style($this->getInstance(), $style, $set);
	}

	/**
	 * 위치, 크기 동시 설정 
	 *
	 * @param int $x 
	 * @param int $y 
	 * @param int $width 
	 * @param int $height 
	 */
	public function setBounds($x, $y, $width, $height) { 
		$this->setPosition($x, $y);
		$this->setSize($width, $height);
	}

	/**
	 * 폰트 설정 
	 *
	 * @param mixed $font 
	 * @param bool $redraw 
	 */
	public function setFont($font, $redraw = false	) { 
		return wb_set_font($this->getInstance(), WBApplication::getInstance($font), $redraw);
	}

	/**
	 * 위치, 영역 얻어오기 
	 * 
	 */
	public function getBounds($lparam = false) { 
		$size = $this->getSize($lparam);
		$pos = $this->getPosition($lparam);
		
		return $size + $pos;
	}


	/**
	 * 객체 문자열 얻어오기 
	 *
	 * @return string 
	 */
	public function toString() { 
		$temp = get_class($this).PHP_EOL;

		return $temp;
	}

	/**
	 * WBC_REDRAW 이벤트 실행 
	 *
	 * repaint() 메소드로 Graphics 객체를 넘겨준다. 
	 */
	public function onRedraw($eo) { 
		// 현재 객체를 다시 그린다. 
		$this->repaint($this->getGraphics($eo));
	}

	/**
	 * WBC_RESIZE 이벤트 실행 
	 *
	 * doLayout() 메소드를 실행 
	 */
	public function onResize() { 
		// 레이아웃을 다시 그리고 
		$this->doLayout();
	}
	
	/**
	 * 해당 위치 좌표로 구하기 
	 * 
	 * @param bool $lparam
	 * @return array
	 */
	public function getRect($lparam = false) { 
		$bounds = $this->getBounds($lparam);
		
		return array(
			'x1' => $bounds['x'],
			'y1' => $bounds['y'],
			'x2' => $bounds['x'] + $bounds['width'],
			'y2' => $bounds['y'] + $bounds['height'],
		);
	}

	/**
	 * WBGraphics 객체 생성 
	 *
	 * @return WBGraphics 
	 */
	public function getGraphics($eo = null) {
		return new WBGraphics($eo->buffer, $this);
	}

	/**
	 * WinBinder 내부에서 사용하는 구조체를 리턴해준다. 
	 *
	 * 
	 * @see WBStruct
	 * @see WBOBJ 
	 */
	public function getHwnd() { 
		if (!$this->_hwnd) { 
			$this->_hwnd = new WBOBJ($this);
		}

		return $this->_hwnd;
	}
	
	/**
	 * 윈도우 dll 기반 함수 사용 
	 * 
	 * @return mixed
	 */
	public function extern() { 
		$params = func_get_args();
		
		$func = array_shift($params);
		
		// default is user32.dll   
		if (strpos($func, '.') === false) { 
			$func = "user.".$func;
		}
		
		// 커널 생성 
		$module =  explode(".", $func);
		
		$dll = $module[0];
		$func = $module[1];
		
		// this object prepend at params
		array_unshift($params, $this);
		
		return call_user_func_array(array(wbmodule($dll), $func), $params);
	}

	/**
	 * id에 해당하는 컨트롤의 instance를 얻어온다. 
	 *
	 * @return resource 
	 */
	public function getControl($id) { 
		return wb_get_control($this->getInstance(), $id);
	}

	/**
	 * Control 에 메세지를 보낸다. 
	 *
	 */
	public function send($message, $wparam, $lparam) { 
		return WBLibrary::send($this->getInstance(), $message, $wparam, $lparam);
	}
	
	/**
	 * 포인트가 현재 위치에 있는지 체크 
	 * 
	 * @param int $x
	 * @param int $y
	 * @return bool
	 */
	public function isArea($x, $y) { 
		$bounds = $this->getBounds(true);
		
		$_x = $bounds['x'];
		$_y = $bounds['y'];
		$_x2 = $_x + $bounds['width'];
		$_y2 = $_y + $bounds['height'];
		
		if ($_x <= $x && $x <= $_x2) { 
			if ($_y <= $y && $y <= $_y2) {
				return true;
			}	
		}
		
		return false;
	}
}

?>